package com.spa.infrastructure.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {

    public static final String YMD_HMS = "yyyy-MM-dd HH:mm:ss";
    public static void main(String[] args) throws ParseException {
//        System.out.println(date2Str(getStartTimeOfCurrentMonth(str2Date("2024-01", "yyyy-MM"))));
//        System.out.println(date2Str(getEndTimeOfCurrentMonth(str2Date("2024-01", "yyyy-MM"))));
//        System.out.println(DateUtil.date2Str(DateUtil.getStartTimeOfCurrentDay(str2Date(getStartOrEndDayOfMonth(LocalDate.now().minusMonths(1), true),"yyyy-MM-dd"))));
//        System.out.println(DateUtil.date2Str(DateUtil.getEndTimeOfCurrentDay(str2Date(getStartOrEndDayOfMonth(LocalDate.now().minusMonths(1), false),"yyyy-MM-dd"))));
//        System.out.println(getStartOrEndDayOfMonth(LocalDate.now().minusMonths(1), true));
//        System.out.println(getStartOrEndDayOfMonth(LocalDate.now().minusMonths(1), false));
        LocalDate today = LocalDate.now();
        String beginTime = today.atStartOfDay().format(DateTimeFormatter.ofPattern(DateUtil.YMD_HMS));
        System.out.println(beginTime);
        System.out.println(today.plusDays(1).atStartOfDay().format(DateTimeFormatter.ofPattern(DateUtil.YMD_HMS)));
    }

    public static boolean isEq(LocalDateTime localDateTime, LocalDateTime localDateTime1) {
        return localDateTime1.getYear() == localDateTime.getYear()
                && localDateTime1.getMonth() == localDateTime.getMonth()
                && localDateTime1.getDayOfMonth() == localDateTime.getDayOfMonth()
                && localDateTime1.getHour() == localDateTime.getHour()
                && localDateTime1.getMinute() == localDateTime.getMinute();
    }
    public static Date localDate2Date(LocalDate localDate) {
        if(null == localDate) {
            return null;
        }
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date str2Date(String time, String pattern) throws ParseException {
        SimpleDateFormat ft = new SimpleDateFormat(pattern);
        return ft.parse(time);
    }

    public static String date2Str(Date date) {
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return ft.format(date);
    }
    /**
     * 获取指定天的开始时间
     * @return
     */
    public static Date getStartTimeOfCurrentDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定天的结束时间
     * @return
     */
    public static Date getEndTimeOfCurrentDay(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定周的开始时间
     * @return
     */
    public static Date getStartTimeOfCurrentWeek(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的结束时间
     * @return
     */
    public static Date getEndTimeOfCurrentWeek(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.setFirstDayOfWeek(Calendar.MONDAY);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的开始时间
     * @return
     */
    public static Date getStartTimeOfCurrentMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),1);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定月的结束时间
     * @return
     */
    public static Date getEndTimeOfCurrentMonth(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        int maxMonthDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH),maxMonthDay);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定年的开始时间 注意月份要减1
     * @return
     */
    public static Date getStartTimeOfCurrentYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),0,1);
        setMinTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 获取指定年的结束时间 注意月份要减1
     * @return
     */
    public static Date getEndTimeOfCurrentYear(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.setTime(date);
        calendar.set(calendar.get(Calendar.YEAR),11,31);
        setMaxTimeOfDay(calendar);
        return calendar.getTime();
    }

    /**
     * 设置当天的开始时间
     * @param calendar
     */
    private static void setMinTimeOfDay(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.MILLISECOND, 0);
    }

    /**
     * 设置当天的结束时间
     * @param calendar
     */
    private static void setMaxTimeOfDay(Calendar calendar) {
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.MILLISECOND, 999);
    }

    /**
     * @Title: getStartOrEndDayOfMonth
     * @Description  获取本月的第一天或最后一天
     * @Date: 2019/7/23 11:50
     * @Param: [today, isFirst: true 表示开始时间，false表示结束时间]
     * @return: java.lang.String
     * @Exception:
     */
    public static String getStartOrEndDayOfMonth(LocalDate today, Boolean isFirst){
        LocalDate resDate = LocalDate.now();
        if (today == null) {
            today = resDate;
        }
        Month month = today.getMonth();
        int length = month.length(today.isLeapYear());
        if (isFirst) {
            resDate = LocalDate.of(today.getYear(), month, 1);
        } else {
            resDate = LocalDate.of(today.getYear(), month, length);
        }
        return resDate.toString();
    }

    /**
     * @Title: getStartOrEndDayOfQuarter
     * @Description  获取本季度的第一天或最后一天
     * @Date: 2019/7/23 13:46
     * @Param: [today, isFirst: true 表示开始时间，false表示结束时间]
     * @return: java.lang.String
     * @Exception:
     */
    public static String getStartOrEndDayOfQuarter(LocalDate today, Boolean isFirst){
        LocalDate resDate = LocalDate.now();
        if (today == null) {
            today = resDate;
        }
        Month month = today.getMonth();
        Month firstMonthOfQuarter = month.firstMonthOfQuarter();
        Month endMonthOfQuarter = Month.of(firstMonthOfQuarter.getValue() + 2);
        if (isFirst) {
            resDate = LocalDate.of(today.getYear(), firstMonthOfQuarter, 1);
        } else {
            resDate = LocalDate.of(today.getYear(), endMonthOfQuarter, endMonthOfQuarter.length(today.isLeapYear()));
        }
        return resDate.toString();
    }

    /**
     * @Title: getStartOrEndOfYear
     * @Description  获取本年的第一天或最后一天
     * @Date: 2019/7/23 13:48
     * @Param: [today, isFirst: true 表示开始时间，false表示结束时间]
     * @return: java.lang.String
     * @Exception:
     */
    public static String getStartOrEndDayOfYear(LocalDate today, Boolean isFirst){
        LocalDate resDate = LocalDate.now();
        if (today == null) {
            today = resDate;
        }
        if (isFirst) {
            resDate = LocalDate.of(today.getYear(), Month.JANUARY, 1);
        } else {
            resDate = LocalDate.of(today.getYear(), Month.DECEMBER, Month.DECEMBER.length(today.isLeapYear()));
        }
        return resDate.toString();
    }
}